home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.mactech.com 2010
/
ftp.mactech.com.tar
/
ftp.mactech.com
/
machack
/
Hacks96
/
WhenInRome.sit
/
When In Rome
/
INIT.c
next >
Wrap
C/C++ Source or Header
|
1996-06-22
|
3KB
|
161 lines
// When In Rome
// Mac Hack XI - MCMXCVI
// Barry Semo
// barrys@netcom.com
#include "A4Stuff.h"
#include "SetupA4.h"
#include <LString.h>
typedef pascal void (*DrawStringProc)(ConstStr255Param s);
typedef pascal short (*StringWidthProc)(ConstStr255Param s);
pascal void DrawStringPatch(ConstStr255Param s);
pascal short StringWidthPatch(ConstStr255Param s);
Boolean IsDigit(char c);
void ToRoman(long decimal, Str255 roman);
void ParseString(Str255 string);
DrawStringProc gOldDrawStringAddr;
StringWidthProc gOldStringWidthAddr;
Str15 gSymbols[] = {"\pM", "\pCM", "\pD", "\pCD", "\pC", "\pXC", "\pL",
"\pXL", "\pX", "\pIX", "\pV", "\pIV", "\pI"};
short gValue[13] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
void main(void)
{
long oldA4;
Handle h;
// a4 world
oldA4 = SetCurrentA4();
RememberA4();
// detach init resource
h = Get1Resource('INIT', 0);
if (h) DetachResource(h);
// initialize
gOldDrawStringAddr = 0L;
// patch
gOldDrawStringAddr = (DrawStringProc)GetToolTrapAddress(_DrawString);
SetToolTrapAddress((UniversalProcPtr)DrawStringPatch, _DrawString);
gOldStringWidthAddr = (StringWidthProc)GetToolTrapAddress(_StringWidth);
SetToolTrapAddress((UniversalProcPtr)StringWidthPatch, _StringWidth);
// restore a4
SetA4(oldA4);
}
// DrawString patch that converts a number to roman numeral equivalents
pascal void DrawStringPatch(ConstStr255Param s)
{
long oldA4;
LStr255 decimalNumber;
Str255 tempString;
oldA4 = SetUpA4();
LString::CopyPStr(s, tempString);//tempCopy
ParseString(tempString);
gOldDrawStringAddr(tempString);
RestoreA4(oldA4);
}
// StringWidth patch that returns the width of a converted string
pascal short StringWidthPatch(ConstStr255Param s)
{
long oldA4;
LStr255 decimalNumber;
Str255 tempString;
short width;
oldA4 = SetUpA4();
LString::CopyPStr(s, tempString);//temp copy
ParseString(tempString);
width = gOldStringWidthAddr(tempString);
RestoreA4(oldA4);
return width;
}
// return if a char is a digit 0-9
Boolean IsDigit(char c)
{
return (c >= '0') && (c <= '9');
}
void ToRoman(long decimal, Str255 roman)
{
short i=0;
LStr255 destStr;
//convert to roman, reducing number by largest roman numeral first,
//working downward
while (decimal > 0) {
if (gValue[i] <= decimal)
{
destStr += gSymbols[i];
decimal -= gValue[i];
}
else
i++;
}
//copy it back
LString::CopyPStr(destStr, roman);
}
// parse a string for embedde numbers, converting them to roman numerals, and
// regParseStringenerating the string
void ParseString(Str255 string)
{
LStr255 destStr("\p");
Str255 romanNum;
long currentNum = 0L;
short length = string[0];
short i;
Boolean seenDigit = false;
for (i= 1; i<= length; i++)
{
if (IsDigit(string[i]))
{
seenDigit = true;
currentNum = (currentNum*10) + (string[i]-'0');//accumulate number
}
else//not a digit
if (seenDigit)//just terminated a number
{
ToRoman(currentNum, romanNum);
destStr += romanNum;
destStr += string[i];
//reset for next time
seenDigit = false;
currentNum = 0L;
}
else
destStr += string[i];
}
// if a number was being accumulated, terminate it
if (currentNum != 0L)
{
ToRoman(currentNum, romanNum);
destStr += romanNum;
}
// copy back to parameter passed in
LString::CopyPStr(destStr, string);
}